home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / xlib04.zip / XCLIPBM.ASM < prev    next >
Assembly Source File  |  1992-11-12  |  13KB  |  492 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XCLIPPBM
  3. ;
  4. ; This module was written by Matthew MacKenzie
  5. ; matm@eng.umd.edu
  6. ;
  7. ; Clipped transfer of planar bitmaps from system memory to video memory.
  8. ;
  9. ; Compile with TASM.
  10. ; C near-callable.
  11. ;
  12. ; ****** XLIB - Mode X graphics library                ****************
  13. ; ******                                               ****************
  14. ; ****** Written By Themie Gouthas                     ****************
  15. ;
  16. ; egg@dstos3.dsto.gov.au
  17. ; teg@bart.dsto.gov.au
  18. ;-----------------------------------------------------------------------
  19.  
  20. include xlib.inc
  21. include xclippbm.inc
  22.  
  23.  
  24.     .data
  25.  
  26.     align 2
  27.  
  28. ; global clipping variables
  29. _TopClip        dw      (?)
  30. _BottomClip     dw      (?)
  31. _LeftClip       dw      (?)
  32. _RightClip      dw      (?)
  33.  
  34. ; VGA plane masks
  35. ColumnMask      db      011h,022h,044h,088h
  36.  
  37. ; bit delay timers
  38. LeftDelay       db      0, 1, 2, 4
  39. RightDelay      db      0, 4, 2, 1
  40.  
  41.  
  42. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  43. ; _x_clip_pbm
  44. ;
  45. ; C near-callable as:
  46. ;
  47. ; void x_clip_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);
  48. ;
  49. ; Bitmap is a planar bitmap, in the regular Xlib format.
  50. ;
  51. ; ax, bx, cx, and dx go south.
  52.  
  53.     .code
  54.  
  55.     public _x_clip_pbm
  56.     align   2
  57. _x_clip_pbm proc
  58. ARG     X:word, Y:word, ScreenOffs:word, Bitmap:dword
  59. LOCAL   left_counter:word, right_counter:word, \
  60.         column:word, clipped_height:word, clipped_width:word, \
  61.         screen_pos:word, bitmap_pos:word, bitmap_size:word, \
  62.         VGA_mask:word, width_copy, height_temp:word, \
  63.         screen_width:word=LocalStk
  64.     push bp
  65.     mov bp, sp
  66.     sub sp, LocalStk
  67.     push si
  68.     push di
  69.     push ds
  70.  
  71. ; sociopathic cases: are the clipping bounds out of order?
  72.     mov ax, _TopClip
  73.     cmp ax, _BottomClip
  74.     jg @@GetOut
  75.     mov ax, _LeftClip
  76.     cmp ax, _RightClip
  77.     jle @@ReasonableAndProper
  78. @@GetOut:
  79.     jmp @@OuttaHere     ; for conditional branches
  80.  
  81. @@ReasonableAndProper:
  82.  
  83. ; we need to use both the tables in ds and the height and width of the bitmap
  84.     les si, Bitmap
  85.  
  86. ; vertical position
  87.     xor cx, cx
  88.     mov cl, byte ptr es:[si + 1] ; height of bitmap
  89.     xor ax, ax
  90.     mov al, byte ptr es:[si] ; width of bitmap
  91.     mul cx
  92.     mov bitmap_size, ax
  93.     mov ax, Y
  94.     cmp ax, _BottomClip ; top edge below clipping box?
  95.     jg @@GetOut
  96.  
  97.     mov bx, cx
  98.     add bx, ax
  99.     dec bx              ; bottom edge = Y + height - 1
  100.     cmp bx, _TopClip
  101.     jl @@GetOut
  102.     sub bx, _BottomClip ; bottom margin = bottom edge - BottomClip
  103.     jle @@NoBottomClip
  104.     sub cx, bx          ; clip bottom margin from height
  105. @@NoBottomClip:
  106.     mov bx, _TopClip
  107.     sub bx, ax          ; top margin = TopClip - Y
  108.     jle @@NoTopClip
  109.     add ax, bx          ; top edge = Y + top margin
  110.     sub cx, bx          ; clip top margin from height
  111.     jmp @@KeepMargin
  112. @@NoTopClip:
  113.     xor bx, bx
  114. @@KeepMargin:
  115.     mov clipped_height, cx
  116.  
  117.     mul _ScrnLogicalByteWidth
  118.     mov di, ax
  119.     add di, ScreenOffs  ; row of upper-left corner of blit
  120.  
  121.     mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)
  122.     mov ax, cx
  123.     mul bx
  124.     add si, ax
  125.     add si, 2           ; starting position in bitmap
  126.  
  127. ; horizontal position
  128.     mov width_copy, cx
  129.     mov dx, X
  130.     cmp dx, _RightClip
  131.     jg @@GetOut
  132.     mov dx, 0           ; unclipped value for right delay
  133.  
  134.     mov ax, cx
  135.     shl ax, 2           ; width in pixels
  136.     add ax, X
  137.     dec ax              ; right edge = X + width in pixels - 1
  138.     cmp ax, _LeftClip
  139.     jl @@GetOut
  140.     sub ax, _RightClip  ; right margin = right edge - RightClip
  141.     jle @@NoRightClip
  142.     mov bx, ax
  143.     and bx, 3
  144.     mov dl, RightDelay[bx]
  145.     shr ax, 2
  146.     sub cx, ax          ; subtract clipped bytes from width
  147. @@NoRightClip:
  148.     mov right_counter, dx
  149.     mov dx, 0           ; unclipped value for left delay
  150.     mov ax, _LeftClip
  151.     sub ax, X           ; left margin = LeftClip - X
  152.     jle @@NoLeftClip
  153.     mov bx, ax
  154.     and bx, 3
  155.     mov dl, LeftDelay[bx]
  156.     add ax, 3
  157.     shr ax, 2           ; left margin/4, rounded up
  158.     sub cx, ax          ; subtract clipped bytes from width
  159.     add si, ax          ; move starting position in bitmap past margin
  160.     add di, ax          ; move starting position on screen past margin
  161. @@NoLeftClip:
  162.     mov left_counter, dx
  163.     mov clipped_width, cx
  164.  
  165.     mov ax, X           ; add x coordinate to screen position
  166.     mov bx, ax
  167.     shr ax, 2
  168.     add di, ax
  169.  
  170.     mov dx, SC_INDEX
  171.     mov al, MAP_MASK
  172.     out dx, al
  173.     inc dx
  174.  
  175.     and bx, 3           ; initial mask
  176.     xor ax, ax
  177.     mov al, ColumnMask[bx]
  178.     mov VGA_mask, ax
  179.     out dx, al          ; initial mask
  180.  
  181.     mov column, 4
  182.     mov bitmap_pos, si
  183.     mov screen_pos, di
  184.     mov ax, _ScrnLogicalByteWidth
  185.     mov screen_width, ax ; since we move ds
  186.  
  187. ; we've used all our tables, so we can change ds to point to the bitmap,
  188. ; and es to point to the screen
  189.     mov ds, word ptr [Bitmap + 2]
  190.     mov ax, SCREEN_SEG
  191.     mov es, ax
  192.  
  193.     cld                 ; strings go forward
  194.     mov bx, width_copy
  195.     sub bx, clipped_width ; bytes to advance one line in bitmap
  196.  
  197. ; let's actually draw something for a change
  198. @@WritePlane:
  199.     mov ax, clipped_height
  200.     mov height_temp, ax
  201.     mov dx, screen_width
  202.     sub dx, clipped_width ; bytes to advance one line across screen
  203.  
  204. @@WriteLine:
  205.     mov cx, clipped_width
  206.     shr cx, 1
  207.     rep movsw           ; in they went, two by two...
  208.     adc cx, 0
  209.     rep movsb           ; catch stray last byte, if it's there
  210.     add si, bx          ; advance one bitmap line
  211.     add di, dx          ; advance one screen line
  212.  
  213.     dec height_temp
  214.     jnz @@WriteLine
  215.  
  216.     dec column
  217.     jz @@OuttaHere      ; only four columns per customer, please
  218.     mov dx, SC_INDEX + 1
  219.     rol byte ptr VGA_mask, 1
  220.     adc screen_pos, 0   ; add to location if we've wrapped to plane 0
  221.     mov al, byte ptr VGA_mask
  222.     out dx, al          ; set VGA for next column
  223.  
  224.     shr right_counter, 1
  225.     jnc @@NoRightCounter
  226.     dec clipped_width   ; cut off right edge for later planes
  227.     inc bx
  228. @@NoRightCounter:
  229.     shr left_counter, 1
  230.     jnc @@NoLeftCounter
  231.     inc clipped_width   ; add to left edge for later planes
  232.     dec bx
  233.     dec bitmap_pos
  234.     dec screen_pos
  235. @@NoLeftCounter:
  236.     mov si, bitmap_pos
  237.     add si, bitmap_size
  238.     mov bitmap_pos, si
  239.     mov di, screen_pos
  240.     jmp @@WritePlane
  241.  
  242. @@OuttaHere:
  243.     pop ds
  244.     pop di
  245.     pop si
  246.     mov sp, bp
  247.     pop bp
  248.  
  249.     ret
  250. _x_clip_pbm endp
  251.  
  252.  
  253. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  254. ; _x_clip_masked_pbm
  255. ;
  256. ; C near-callable as:
  257. ;
  258. ; void x_clip_masked_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);
  259. ;
  260. ; Bitmap is a planar bitmap, in the regular Xlib format.
  261. ; The width of the bitmap cannot be greater than 90 bytes, however.
  262. ; Ain't that just criminal?
  263. ;
  264. ; ax, bx, cx, and dx go south.
  265.  
  266.  
  267. ; one branch per pixel is more than enough -- we'll unroll the line-writing
  268. ; loop all the way to try to get a little speed (at the expense, as usual,
  269. ; of a chunk of memory)
  270.  
  271. MaskedPoint macro offset
  272.     mov al, [si + offset]
  273.     or al, al
  274.     jz $+6
  275.     mov es:[di + offset], al
  276.     endm
  277.  
  278. MaskedPointSize     equ     11
  279.  
  280.     public _x_clip_masked_pbm
  281.     align   2
  282. _x_clip_masked_pbm proc
  283. ARG     X:word, Y:word, ScreenOffs:word, Bitmap:dword
  284. LOCAL   left_counter:word, right_counter:word, \
  285.         column:word, clipped_height:word, \
  286.         screen_pos:word, bitmap_pos:word, bitmap_size:word, \
  287.         VGA_mask:word, width_copy, height_temp:word, \
  288.         screen_width:word=LocalStk
  289.     push bp
  290.     mov bp, sp
  291.     sub sp, LocalStk
  292.     push si
  293.     push di
  294.     push ds
  295.  
  296. ; sociopathic cases: are the clipping bounds out of order?
  297.     mov ax, _TopClip
  298.     cmp ax, _BottomClip
  299.     jg @@GetOut
  300.     mov ax, _LeftClip
  301.     cmp ax, _RightClip
  302.     jle @@ReasonableAndProper
  303. @@GetOut:
  304.     jmp @@OuttaHere     ; for conditional branches
  305.  
  306. @@ReasonableAndProper:
  307.  
  308. ; we need to use both the tables in ds and the height and width of the bitmap
  309.     les si, Bitmap
  310.  
  311. ; vertical position
  312.     xor cx, cx
  313.     mov cl, byte ptr es:[si + 1] ; height of bitmap
  314.     xor ax, ax
  315.     mov al, byte ptr es:[si] ; width of bitmap
  316.     mul cx
  317.     mov bitmap_size, ax
  318.     mov ax, Y
  319.     cmp ax, _BottomClip ; top edge below clipping box?
  320.     jg @@GetOut
  321.  
  322.     mov bx, cx
  323.     add bx, ax
  324.     dec bx              ; bottom edge = Y + height - 1
  325.     cmp bx, _TopClip
  326.     jl @@GetOut
  327.     sub bx, _BottomClip ; bottom margin = bottom edge - BottomClip
  328.     jle @@NoBottomClip
  329.     sub cx, bx          ; clip bottom margin from height
  330. @@NoBottomClip:
  331.     mov bx, _TopClip
  332.     sub bx, ax          ; top margin = TopClip - Y
  333.     jle @@NoTopClip
  334.     add ax, bx          ; top edge = Y + top margin
  335.     sub cx, bx          ; clip top margin from height
  336.     jmp @@KeepMargin
  337. @@NoTopClip:
  338.     xor bx, bx
  339. @@KeepMargin:
  340.     mov clipped_height, cx
  341.  
  342.     mul _ScrnLogicalByteWidth
  343.     mov di, ax
  344.     add di, ScreenOffs  ; row of upper-left corner of blit
  345.  
  346.     mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)
  347.     mov ax, cx
  348.     mul bx
  349.     add si, ax
  350.     add si, 2           ; starting position in bitmap
  351.  
  352. ; horizontal position
  353.     mov width_copy, cx
  354.     mov dx, X
  355.     cmp dx, _RightClip
  356.     jg @@GetOut
  357.     mov dx, 0           ; unclipped value for right delay
  358.  
  359.     mov ax, cx
  360.     shl ax, 2           ; width in pixels
  361.     add ax, X
  362.     dec ax              ; right edge = X + width in pixels - 1
  363.     cmp ax, _LeftClip
  364.     jl @@GetOut
  365.     sub ax, _RightClip  ; right margin = right edge - RightClip
  366.     jle @@NoRightClip
  367.     mov bx, ax
  368.     and bx, 3
  369.     mov dl, RightDelay[bx]
  370.     shr ax, 2
  371.     sub cx, ax          ; subtract clipped bytes from width
  372. @@NoRightClip:
  373.     mov right_counter, dx
  374.     mov dx, 0           ; unclipped value for left delay
  375.     mov ax, _LeftClip
  376.     sub ax, X           ; left margin = LeftClip - X
  377.     jle @@NoLeftClip
  378.     mov bx, ax
  379.     and bx, 3
  380.     mov dl, LeftDelay[bx]
  381.     add ax, 3
  382.     shr ax, 2           ; left margin/4, rounded up
  383.     sub cx, ax          ; subtract clipped bytes from width
  384.     add si, ax          ; move starting position in bitmap past margin
  385.     add di, ax          ; move starting position on screen past margin
  386. @@NoLeftClip:
  387.     mov left_counter, dx
  388.     mov ax, cx
  389.     imul ax, (-1 * MaskedPointSize)
  390.     add ax, offset @@LineDone + 2
  391.     mov cx, ax          ; jump offset for plotting
  392.  
  393.     mov ax, X           ; add x coordinate to screen position
  394.     mov bx, ax
  395.     shr ax, 2
  396.     add di, ax
  397.  
  398.     mov dx, SC_INDEX
  399.     mov al, MAP_MASK
  400.     out dx, al
  401.     inc dx
  402.  
  403.     and bx, 3           ; initial mask
  404.     xor ax, ax
  405.     mov al, ColumnMask[bx]
  406.     mov VGA_mask, ax
  407.     out dx, al
  408.  
  409.     mov column, 4
  410.     mov bitmap_pos, si
  411.     mov screen_pos, di
  412.     mov ax, _ScrnLogicalByteWidth
  413.     mov screen_width, ax ; since we move ds
  414.  
  415. ; we've used all our tables, so we can change ds to point to the bitmap,
  416. ; and es to point to the screen
  417.     mov ds, word ptr [Bitmap + 2]
  418.     mov ax, SCREEN_SEG
  419.     mov es, ax
  420.  
  421.     cld                 ; strings go forward
  422.     mov bx, width_copy
  423.  
  424. ; let's actually draw something for a change
  425.     mov ax, clipped_height
  426.     mov height_temp, ax
  427.     mov dx, screen_width
  428.     jmp cx
  429.  
  430. ; 89 bottles of beer on the wall...
  431.     PointLoop = 89
  432.     rept 89
  433.         MaskedPoint PointLoop
  434.         PointLoop = PointLoop - 1
  435.     endm
  436. ; one bottle of beer...
  437.  
  438. ; final point needs a different branch offset, so we don't use MaskedPoint
  439.     mov al, [si]
  440.     or al, al
  441.     jz @@LineDone
  442.     mov es:[di], al
  443.  
  444. @@LineDone:
  445.     add si, bx          ; advance one bitmap line
  446.     add di, dx          ; advance one screen line
  447.     dec height_temp
  448.     jz @@PlaneDone
  449.     jmp cx
  450.  
  451. @@PlaneDone:
  452.     dec column
  453.     jz @@OuttaHere      ; only four columns per customer, please
  454.     mov dx, SC_INDEX + 1
  455.     rol byte ptr VGA_mask, 1
  456.     adc screen_pos, 0   ; move to new column if we've wrapped to plane 0
  457.     mov al, byte ptr VGA_mask
  458.     out dx, al          ; set VGA for next column
  459.  
  460.     shr right_counter, 1
  461.     jnc @@NoRightCounter
  462.     add cx, MaskedPointSize ; cut off right edge for later planes
  463. @@NoRightCounter:
  464.     shr left_counter, 1
  465.     jnc @@NoLeftCounter
  466.     sub cx, MaskedPointSize ; add to left edge for later planes
  467.     dec bitmap_pos
  468.     dec screen_pos
  469. @@NoLeftCounter:
  470.     mov si, bitmap_pos
  471.     add si, bitmap_size
  472.     mov bitmap_pos, si
  473.     mov di, screen_pos
  474.  
  475.     mov ax, clipped_height
  476.     mov height_temp, ax
  477.     mov dx, screen_width
  478.     jmp cx
  479.  
  480. @@OuttaHere:
  481.     pop ds
  482.     pop di
  483.     pop si
  484.     mov sp, bp
  485.     pop bp
  486.  
  487.     ret
  488. _x_clip_masked_pbm endp
  489.  
  490.     end
  491.  
  492.